/**
 * Created by jiachenpan on 16/11/18.
 */

export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null;
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
  let date;
  if (typeof time === 'object') {
    date = time;
  } else {
    if (('' + time).length === 10) time = parseInt(time) * 1000;
    date = new Date(time);
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  };
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key];
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ]; }
    if (result.length > 0 && value < 10) {
      value = '0' + value;
    }
    return value || 0;
  });
  return time_str;
}

export function formatTime(time, option) {
  time = +time * 1000;
  const d = new Date(time);
  const now = Date.now();

  const diff = (now - d) / 1000;

  if (diff < 30) {
    return '刚刚';
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前';
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前';
  } else if (diff < 3600 * 24 * 2) {
    return '1天前';
  }
  if (option) {
    return parseTime(time, option);
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    );
  }
}

export function isExternal(path) {
  return /^(https?:|mailto:|tel:)/.test(path);
}

export function pick(setting) {
  const isObject = some => typeof some === 'object' && some !== null;
  const isArray = some => some instanceof Array;
  const isString = some => typeof some === 'string';

  function typeConvert(value, typeString, ...typeParams) {
    if (!typeString) return value;
    switch (typeString.trim().toLowerCase()) {
      case 'float':
        return parseFloat(value, ...typeParams);
      case 'int':
        return parseInt(value, ...typeParams);
      default:
        return value;
    }
  }

  function deepProp(object, string) {
    const [propKey, propType, ...propTypeParams] = string.split(',');
    const props = propKey.trim().split('.');
    const value = props.reduce(
      (o, key) => (o && isObject(o) ? o[key] : o),
      object
    );
    return {
      key: props[props.length - 1],
      value: typeConvert(value, propType, ...propTypeParams)
    };
  }

  function pickArray(array) {
    return function pickArrayFunc(object) {
      return array.reduce((o, k) => {
        const { key, value } = deepProp(object, k);
        return { ...o, [key]: value };
      }, {});
    };
  }

  function pickObject(objectSetting) {
    return function pickObjectFunc(object) {
      return Object.keys(objectSetting).reduce((o, k) => {
        const { value } = deepProp(object, objectSetting[k]);
        return { ...o, [k]: value };
      }, {});
    };
  }

  if (isArray(setting)) {
    return pickArray(setting);
  }
  if (isObject(setting)) {
    return pickObject(setting);
  }
  // eslint-disable-next-line no-undef
  if (isString(setting)) {
    return obj => deepProp(obj, setting).value;
  }

  throw new Error('参数必须为String、Object、Array类型');
}

export function excludeKeys(object, keys) {
  return Object.keys(object).reduce(
    (o, k) => (keys.includes(k) ? o : { ...o, [k]: object[k] }),
    {}
  );
}

function hasProp(object, prop) {
  return Object.prototype.hasOwnProperty.call(object, prop);
}

export function hasNoneAsciiChar (s) {
  return `${s}`.split('').some(c => c.charCodeAt(0) > 256);
}

export function translateMenuTree(tree, translate) {
  if (!tree) return tree;
  if (Array.isArray(tree)) {
    return tree.map(item => translateMenuTree(item, translate));
  }
  const t = { ...tree };
  const labelProps = ['label', 'name'];
  const childProps = ['children'];
  labelProps.forEach(key => {
    if (!t.title && t[key]) t.title = t[key];
    if (hasProp(t, key) && !hasNoneAsciiChar(t[key])) {
      t.title = translate(t[key]);
    }
  });
  if (Array.isArray(t.children)) {
    t.children = t.children.map(c => translateMenuTree(c, translate));
  }
  if (t.data) {
    t.data = translateMenuTree(t.data, translate);
  }
  return t;
}

export function getFieldsInitValue(fields) {
  const hasProp = (t, k) => Object.prototype.hasOwnProperty.call(t, k);
  return fields.reduce((r, t) => {
    const children = hasProp(t, 'children')
      ? getFieldsInitValue(t.children)
      : null;
    const acc = children ? { ...r, ...children } : { ...r };
    if (hasProp(t, 'initValue') && hasProp(t, 'field')) {
      return { ...acc, [t.field]: t.initValue };
    }
    return acc;
  }, {});
}
